/********************************/
/*	Author:	gong_libin	*/
/*	Date:	2010_01_12	*/
/********************************/

#include "SendMail.h"

int main(int argc,char *argv[])
{
	FILE *fp = NULL;
	int iSocket = 0;
	int iLength = 0;
	int iOptionIndex = 0;
	int iOptionReturn = 0;
	char *pszUser = NULL;
	char *pszPass = NULL;
	struct sockaddr_in stSmtpMail;
	struct hostent *pstHost = NULL;
	char szFile[LOGIN_SIZE] = { 0 };
	char szSmtp[LOGIN_SIZE] = { 0 };
	char szUser[LOGIN_SIZE] = { 0 };
	char szPass[LOGIN_SIZE] = { 0 };
	char szSend[BUFFER_SIZE] = { 0 };
	char szRecv[BUFFER_SIZE] = { 0 };
	char szSrcAddress[LOGIN_SIZE] = { 0 };
	char szDstAddress[LOGIN_SIZE] = { 0 };

	struct option stOptions[] = {
		{"file",1,0,'f'},
		{"mail",1,0,'m'},
		{"user",1,0,'u'},
		{"pass",1,0,'p'},
		{"address",1,0,'a'},
		{"version",0,0,'v'},
		{"help",0,0,'h'},
		{0,0,0,0},
	};

	if( argc < 6 ) {
		PrintHelp();
		return SUCCESS;
	}

	while( 1 ) {
		iOptionReturn = getopt_long(argc,argv,"f:m:u:p:a:vh",stOptions,&iOptionIndex);
		if( iOptionReturn < 0 ) {
			break;
		}
		switch(iOptionReturn) {
			case 'f':	strcpy(szFile,optarg);
					break;
			case 'm':	strcpy(szSmtp,optarg);
					break;
			case 'u':	strcpy(szUser,optarg);
					break;
			case 'p':	strcpy(szPass,optarg);
					break;
			case 'a':	strcpy(szDstAddress,optarg);
					break;
			case 'h':	PrintHelp();
					return SUCCESS;
			case 'v':	printf("Copyright (C) 2010. Product by lb-gong@sohu.com.\n");
					printf("Version 1.0.0 Build on %s %s.\n",__DATE__,__TIME__);
					return SUCCESS;
			default:	return SUCCESS;
		}
	}

	pszUser = (char *)Base64Encode((UCHAR *)szUser,strlen(szUser),&iLength);
	pszPass = (char *)Base64Encode((UCHAR *)szPass,strlen(szPass),&iLength);
	if( !pszUser || !pszPass ) {
		SMTP_MAIL_ERROR("Failed to Base64Encode!\n");
		return FAILURE;
	}

	if( GetSrcAddress(szSrcAddress,szUser,szSmtp) ) {
		SMTP_MAIL_ERROR("Failed to get source address!\n");
		return FAILURE;
	}

	pstHost = gethostbyname(szSmtp);
	if( !pstHost ) {
		SMTP_MAIL_ERROR("%s\n",strerror(errno));
		return FAILURE;
	}

	memset(&stSmtpMail,'\0',sizeof(struct sockaddr_in));
	stSmtpMail.sin_family = AF_INET;
	stSmtpMail.sin_port = htons(SMTP_PORT);
	memcpy(&stSmtpMail.sin_addr,((struct in_addr *)pstHost->h_addr),sizeof(struct in_addr));

	iSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if( iSocket < 0 ) {
		SMTP_MAIL_ERROR("%s\n",strerror(errno));
		return FAILURE;
	}

	if( connect(iSocket,(struct sockaddr *)&stSmtpMail,sizeof(struct sockaddr_in)) < 0 ) {
		SMTP_MAIL_ERROR("%s\n",strerror(errno));
		return FAILURE;
	}

	/* Recv: 220 smtp.sohu.com ESMTP Postfix */
	TRANSFER_SMTP_PACKET(recv,iSocket,szRecv,BUFFER_SIZE);

	/* Send: EHLO localhost */
	CREATE_SMTP_PACKET(szSend,szRecv,"EHLO localhost%s",CRLF);
	TRANSFER_SMTP_PACKET(send,iSocket,szSend,strlen(szSend));
	TRANSFER_SMTP_PACKET(recv,iSocket,szRecv,BUFFER_SIZE);

	/* Send: AUTH LOGIN */
	CREATE_SMTP_PACKET(szSend,szRecv,"AUTH LOGIN%s",CRLF);
	TRANSFER_SMTP_PACKET(send,iSocket,szSend,strlen(szSend));
	TRANSFER_SMTP_PACKET(recv,iSocket,szRecv,BUFFER_SIZE);

	/* Send: user name */
	CREATE_SMTP_PACKET(szSend,szRecv,"%s%s",pszUser,CRLF);
	TRANSFER_SMTP_PACKET(send,iSocket,szSend,strlen(szSend));
	TRANSFER_SMTP_PACKET(recv,iSocket,szRecv,BUFFER_SIZE);

	/* Send: password */
	CREATE_SMTP_PACKET(szSend,szRecv,"%s%s",pszPass,CRLF);
	TRANSFER_SMTP_PACKET(send,iSocket,szSend,strlen(szSend));
	TRANSFER_SMTP_PACKET(recv,iSocket,szRecv,BUFFER_SIZE);

	/* Send: MAIL FROM: <lb-gong@sohu.com> */
	CREATE_SMTP_PACKET(szSend,szRecv,"MAIL FROM:%s%s",szSrcAddress,CRLF);
	TRANSFER_SMTP_PACKET(send,iSocket,szSend,strlen(szSend));
	TRANSFER_SMTP_PACKET(recv,iSocket,szRecv,BUFFER_SIZE);

	/* Send: RCPT TO: <lb-gong@hotmail.com> */
	CREATE_SMTP_PACKET(szSend,szRecv,"RCPT TO:<%s>%s",szDstAddress,CRLF);
	TRANSFER_SMTP_PACKET(send,iSocket,szSend,strlen(szSend));
	TRANSFER_SMTP_PACKET(recv,iSocket,szRecv,BUFFER_SIZE);

	/* Send: DATA */
	CREATE_SMTP_PACKET(szSend,szRecv,"DATA%s",CRLF);
	TRANSFER_SMTP_PACKET(send,iSocket,szSend,strlen(szSend));
	TRANSFER_SMTP_PACKET(recv,iSocket,szRecv,BUFFER_SIZE);

	/* Send: Head */
	CREATE_SMTP_PACKET(szSend,szRecv,"From: %s%sTo: %s%s",szSrcAddress,CRLF,szDstAddress,CRLF);
	strcat(szSend,"Subject: Email\r\n");
	strcat(szSend,"X-mailer: \r\n");
	strcat(szSend,"Mime-Version: 1.0\r\n");
	strcat(szSend,"Content-Type: text/plain;\r\n\t");
	strcat(szSend,"charset=\"gb2312\"\r\n");
	strcat(szSend,"Content-Transfer-Encoding: 7bit\r\n\r\n");
	TRANSFER_SMTP_PACKET(send,iSocket,szSend,strlen(szSend));

	/* Send: Mail */
	fp = fopen(szFile,"r");
	if( !fp ) {
		SMTP_MAIL_ERROR("%s\n",strerror(errno));
		close(iSocket);
		return FAILURE;
	}
	while( fgets(szSend,BUFFER_SIZE,fp) ) {
		TRANSFER_SMTP_PACKET(send,iSocket,szSend,strlen(szSend));
		memset(szSend,'\0',BUFFER_SIZE);
	}
	fclose(fp);

	/* Send: Blank line and a period */
	CREATE_SMTP_PACKET(szSend,szRecv,"%s.%s",CRLF,CRLF);
	TRANSFER_SMTP_PACKET(send,iSocket,szSend,strlen(szSend));
	TRANSFER_SMTP_PACKET(recv,iSocket,szRecv,BUFFER_SIZE);

	/* Send: Quit */
	CREATE_SMTP_PACKET(szSend,szRecv,"QUIT%s",CRLF);
	TRANSFER_SMTP_PACKET(send,iSocket,szSend,strlen(szSend));
	TRANSFER_SMTP_PACKET(recv,iSocket,szRecv,BUFFER_SIZE);

	close(iSocket);

	return SUCCESS;
}

void PrintHelp()
{
	printf("Usage: ./SendMail [options]\n");
	printf("Valid options are:\n");
	printf("-f or --file:		Will Send file.\n");
	printf("-m or --mail:		Smtp server.\n");
	printf("-u or --user:		User name.\n");
	printf("-p or --pass:		Password.\n");
	printf("-a or --address:	Email address.\n");
	printf("-v or --version:	show version.\n");
	printf("-h or --help:		show help.\n");

	return;
}

int GetSrcAddress(char *pszSrcAddress,char *pszUser,char *pszSmtp)
{
	char *pszDot = NULL;

	strcpy(pszSrcAddress,pszUser);
	pszDot = strchr(pszSmtp,'.');
	if( pszDot ) {
		sprintf(pszSrcAddress + strlen(pszSrcAddress),"@%s",pszDot + 1);
	}

	return SUCCESS;
}
